#include "hashtable.h"
#include "hashtable_util.h"
#include "gtest/gtest.h"

void print_hashtable(Hashtable* hashtable){
   printf("----\n");
   for(int i=0; i<hashtable->size; i++){
     if(hashtable->bucket[i]->key!=NULL){
        Node* currentNode = hashtable->bucket[i];
        do {
            printf("%s  ",currentNode->key);
            currentNode = currentNode->pNext;
        } while(currentNode!=NULL);
        printf("\n");
     }
     else
         printf("NULL\n");
  }


}

// Tests that the Foo::Bar() method does Abc.
TEST(hash_test,test1)  {
  EXPECT_EQ(48,hash("0",200));
}

TEST(hash_test,test2)  {
  EXPECT_EQ(144,hash("000",200));
}

TEST(hash_test,test3)  {
  for(int i=1; i<200; i++){
    EXPECT_GE(i,hash("gfdsffgasdgsafdsgag",i));
  }  
}

TEST(hashtable,creation_deletion) {
  Hashtable* hashtable = create_hashtable(10);
  hashtable_add(hashtable,"ololo","ololo");
  delete_hashtable(hashtable);
  //TODO check if memory was disposed
  //EXPECT_EQ(NULL,hashtable);
}

TEST(node,create_node){
   Node* pNode = create_node("preved", "ololo",NULL);
   ASSERT_STREQ("preved",pNode->key);
   ASSERT_NE("preved",pNode->key);
}

TEST(hashtable,add_find){
  Hashtable* hashtable = create_hashtable(5);
  hashtable_add(hashtable,"hello1","foo");
  hashtable_add(hashtable,"hello3","foo");
  hashtable_add(hashtable,"hello5","foo");
  hashtable_add(hashtable,"hello5","foo");
  hashtable_add(hashtable,"hello2","foo");
  hashtable_add(hashtable,"hello2","foo");
  hashtable_add(hashtable,"hello5","foo");
  hashtable_add(hashtable,"hello4","bar");
  print_hashtable(hashtable);
  EXPECT_STREQ("foo",hashtable_find(hashtable,"hello1"));
  EXPECT_STREQ("foo",hashtable_find(hashtable,"hello5"));
  EXPECT_STREQ("foo",hashtable_find(hashtable,"hello3"));
  EXPECT_STREQ("bar",hashtable_find(hashtable,"hello4"));
  EXPECT_EQ(NULL,hashtable_find(hashtable,"just hello"));
  //delete_hashtable(hashtable);
}

/*
TEST(hashtable,delete){
  Hashtable* hashtable = create_hashtable(3);
  hashtable_add(hashtable,"hello1","foo");
  hashtable_add(hashtable,"hello2","foo");
  hashtable_add(hashtable,"hello3","foo");
  hashtable_add(hashtable,"hello4","bar");
  print_hashtable(hashtable);
//  hashtable_delete(hashtable, "hello3");
  hashtable_delete(hashtable, "hello1");
  print_hashtable(hashtable);
   EXPECT_STREQ("foo",hashtable_find(hashtable,"hello2"));
  EXPECT_STREQ("bar",hashtable_find(hashtable,"hello4"));
  EXPECT_EQ(NULL,hashtable_find(hashtable,"hello1"));
  EXPECT_EQ(NULL,hashtable_find(hashtable,"hello3"));
  //delete_hashtable(hashtable);

}
*/


TEST(hashtable,iterators){

  Hashtable* hashtable = create_hashtable(3);
  hashtable_add(hashtable,"hello1","foo");
  hashtable_add(hashtable,"hello2","foo");
  hashtable_add(hashtable,"hello3","foo");
  hashtable_add(hashtable,"hello4","bar");
  print_hashtable(hashtable);
  EXPECT_STREQ("hello2",hashtable_getFirst(hashtable)->key);
  EXPECT_STREQ("hello3",hashtable_getNext(hashtable,hashtable_getFirst(hashtable))->key);
  //delete_hashtable(hashtable);
}



/*
TEST(hashtable, expand){

  Hashtable* hashtable = create_hashtable(3);
  hashtable_add(hashtable,"hello1","foo");
  hashtable_add(hashtable,"hello2","foo");
  hashtable_add(hashtable,"hello3","foo");
  hashtable_add(hashtable,"hello4","bar");
  print_hashtable(hashtable);

  hashtable = hashtable_expand(hashtable);
  print_hashtable(hashtable);
  delete_hashtable(hashtable); //
}
*/
int main(int argc, char **argv) {
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
